package com.dirven.game;

import java.util.ArrayList;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.SpriteCache;
import com.dirven.game.sprite.Sprite;
import com.dirven.game.sprite.TunnelPhoton;

public class GridBackground {

	private static ArrayList<TunnelPhoton> photons;
	
	final static int MAX_PHOTONS = 15;
	
	final static byte NO_OPEN_WALLS = -1;
	private static byte currentlyOpenWall = NO_OPEN_WALLS;
	
	/**
	 * Spawns a photon at a random position on the screen.
	 */
	private static void spawnPhoton() {
		int x = Misc.randomNumber(0, DirVenGame.screenWidth),
			y = Misc.randomNumber(0, DirVenGame.screenHeight);
		
		int direction = Sprite.DIRECTION_NORTH;
		// Make TunnelPhoton go in the direction of the opened up tunnel.
		direction = getFlowDirection();
		
		int photon = Misc.randomNumber(0, 4),
			photonSize = TunnelPhoton.PHOTONSIZE_32;
		switch(photon) {
			case 0: photonSize = TunnelPhoton.PHOTONSIZE_32; break;
			case 1: photonSize = TunnelPhoton.PHOTONSIZE_64; break;
			case 2: photonSize = TunnelPhoton.PHOTONSIZE_128; break;
			case 3: photonSize = TunnelPhoton.PHOTONSIZE_256; break;
		}
		TunnelPhoton tp = new TunnelPhoton((float)x, (float)y, photonSize, direction);
		photons.add( tp );
	}
	
	private static void hideSprite(com.badlogic.gdx.graphics.g2d.Sprite spr) {
		spr.setPosition(-spr.getWidth()-1000, 0.0f);
	}
	
	private static void hideAllSprites(com.badlogic.gdx.graphics.g2d.Sprite spr) {
		if(photons != null) {

			for(TunnelPhoton tp : photons) {
				hideSprite(tp);
			}
		}
	}
	
	private static void repositionAllSprites() {
		if(photons != null) {
			for(TunnelPhoton tp : photons) {
				int x = Misc.randomNumber(0, DirVenGame.screenWidth),
					y = Misc.randomNumber(0, DirVenGame.screenHeight);
					
				tp.setPosition(x, y);
			}
		}
	}
	
	private static void resetAllSprites() {
		if(photons != null) {
			int direction = getFlowDirection();
		
			for(TunnelPhoton tp : photons) {
				tp.reset(direction);
				
				int x = Misc.randomNumber(0, DirVenGame.screenWidth),
					y = Misc.randomNumber(0, DirVenGame.screenHeight);
				
				tp.setPosition(x, y);
			}
		}
	}
	
	public static int getFlowDirection() {
		int direction = Sprite.DIRECTION_NORTH;
		// Make TunnelPhoton go in the direction of the opened up tunnel.
		if(currentlyOpenWall == Grid.WALL_NORTH) {
			direction = Sprite.DIRECTION_NORTH;
		} else if(currentlyOpenWall == Grid.WALL_SOUTH) {
			direction = Sprite.DIRECTION_SOUTH;
		} else if(currentlyOpenWall == Grid.WALL_EAST) {
			direction = Sprite.DIRECTION_EAST;
		} else if(currentlyOpenWall == Grid.WALL_WEST) {
			direction = Sprite.DIRECTION_WEST;
		}
		return direction;
	}
	
	/**
	 * Gets the currently opened wall.
	 * @return
	 */
	private static byte getOpenedWall() {
		if(Grid.wallNorthBlocked == false) {
			return Grid.WALL_NORTH;
		} else if(Grid.wallSouthBlocked == false) {
			return Grid.WALL_SOUTH;
		} else if(Grid.wallEastBlocked == false) {
			return Grid.WALL_EAST;
		} else if(Grid.wallWestBlocked == false) {
			return Grid.WALL_WEST;
		}
		return NO_OPEN_WALLS;
	}
	
	/**
	 * When changing walls clear the photons
	 * @param newWall
	 */
	private static void changeOpenedWall(byte newWall) {
		/*if(photons != null) {
			
			photons.clear();
		}
		
		photons = null;*/
		
		currentlyOpenWall = newWall;
		
		resetAllSprites();
	}
	
	/**
	 * Update the background
	 */
	public static void update() {
		// If one of the grid walls is unblocked
		if(!Grid.wallNorthBlocked || !Grid.wallSouthBlocked || !Grid.wallEastBlocked || !Grid.wallWestBlocked) {
			
			byte wall = getOpenedWall();
			if(currentlyOpenWall != wall) {
				changeOpenedWall(wall);
			}
			
			if(photons == null) {
				photons = new ArrayList<TunnelPhoton>();
			}
			
			// if the number of photons is less than the maximum
			if(photons.size() < Misc.randomNumber(5, MAX_PHOTONS)) {
				
				int numToAdd = Misc.randomNumber(1, MAX_PHOTONS-photons.size());
				
				// Spawn a random number of photons
				for(int i = 0; i < numToAdd; i++) {
					spawnPhoton();
				}
			}
			
			// Update the photons and remove the ones that are despawned.
			for(int i = 0; i < photons.size(); i++) {
				TunnelPhoton tp = photons.get(i);
				// Update the photon
				tp.update();
				
				// If it's despawning, remove it.
				if(tp.isDespawning()) {
					int x = Misc.randomNumber(0, DirVenGame.screenWidth),
						y = Misc.randomNumber(0, DirVenGame.screenHeight);
						
					tp.setPosition(x, y);
					
					tp.setDespawning(false);
				}
			}
			
		// If all walls are blocked (IE inside a station...)
		} else {
			
			// Remove the photons.
			if(photons != null) {
				photons.clear();
			}
			photons = null;
			
			currentlyOpenWall = NO_OPEN_WALLS;
		}
	}
	
	public static void render(SpriteBatch batch) {
		// Update
		update();
		
		// If there are photons draw them.
		if(photons != null && photons.size() > 0) {
			for(TunnelPhoton tp : photons) {
				tp.setPosition(tp.getX(), tp.getY());
				tp.draw(batch);
			}
			
		}
		
	}

	public static void dispose() {
		for(TunnelPhoton tp : photons) {
			tp.getTexture().dispose();
			tp = null;
		}
		photons.clear();
		photons = null;
	}

}
